package com.policyCloud.policyOauth.configuration;

import com.google.common.base.Joiner;
import com.policyCloud.policyOauth.dao.CenterUsersMapper;
import com.policyCloud.policyOauth.pojo.CenterRole;
import com.policyCloud.policyOauth.pojo.CenterSitemap;
import com.policyCloud.policyOauth.pojo.CenterUsers;
import com.policyCloud.policyOauth.pojo.CenterUsersCriteria;
import com.policyCloud.policyOauth.security.CustomUserDetails;
import com.policyCloud.policyOauth.security.filter.CustomLogoutHandler;
import com.policyCloud.policyOauth.security.filter.MacLoginUrlAuthenticationEntryPoint;
import com.policyCloud.policyOauth.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;

import javax.annotation.Resource;
import java.util.*;

/**
 * @所在包: com.oauth2.configuration
 * @文件名:SecurityConfiguration
 * @版权:四川兴财信息产业发展有限公司.
 * @项目:centrality
 * @功能描述: Security启动配置
 * @创建人: 龟派气功rmk
 * @时间: 2018-11-09 15:38
 **/
@Order(2)
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

   @Resource
   CenterUsersMapper userMapper;
    @Resource
    UserService userService;


    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.csrf().disable().requestMatchers().antMatchers("/oauth/**")
//                .and()
//                .authorizeRequests()
//                .antMatchers("/oauth/**").authenticated();
        http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and().requestMatchers().anyRequest()
                .and().formLogin().permitAll()
                .and().authorizeRequests().antMatchers("/oauth/*").permitAll()
                .anyRequest().authenticated()
                .and().logout()
                .logoutUrl("/logout")
                .clearAuthentication(true)
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
                .addLogoutHandler(customLogoutHandler())
                .and().exceptionHandling().authenticationEntryPoint(macLoginUrlAuthenticationEntryPoint());

    }

    @Bean
    public AuthenticationEntryPoint macLoginUrlAuthenticationEntryPoint() {
        return new MacLoginUrlAuthenticationEntryPoint("/login");
    }

    @Bean
    public CustomLogoutHandler customLogoutHandler() {
        return new CustomLogoutHandler();
    }


    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
//
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetailsService re = new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
                CenterUsersCriteria criteriaObj = new CenterUsersCriteria();
                CenterUsersCriteria.Criteria criteria= criteriaObj.createCriteria();
                criteria.andNickNameEqualTo(name);
                CenterUsersCriteria.Criteria criteria2 = criteriaObj.or();
                criteria2.andEmailEqualTo(name);
                CenterUsersCriteria.Criteria criteria3 = criteriaObj.or();
                criteria3.andMobileEqualTo(name);
                List<CenterUsers> users =  userMapper.selectByExample(criteriaObj);
                if (CollectionUtils.isNotEmpty(users) && users.size() ==1) {
                    List<String> roleName_perName_List = new ArrayList<>();
                    CenterUsers s = users.get(0);
                    Map<String,Object> remMap = null;
                    try {
                        remMap= userService.getRoleAndPer(s);
                    }catch (RuntimeException e){
                        throw new UsernameNotFoundException("获取角色权限发生错误");
                    }
                    if(remMap != null){
                        if(remMap.containsKey("roles")){
                            List<CenterRole> roles = (List<CenterRole>) remMap.get("roles");
                            roles.stream().forEach(x->{
                                roleName_perName_List.add("ROLE_"+x.getRoleName());
                            });
                        }
                        if(remMap.containsKey("perms")){
                            List<CenterSitemap> perms = (List<CenterSitemap>) remMap.get("perms");
                            perms.stream().forEach(x->{
                                roleName_perName_List.add("Perm_"+x.getName());
                            });
                        }

                    }
                    String symbol = Joiner.on(",").join(roleName_perName_List);
                    // 创建spring security安全用户
                    CustomUserDetails user = new CustomUserDetails();
                    user.setUserId(s.getId().toString());
                    user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(symbol));
                    user.setUsername(s.getUserName());
                    user.setPassword(s.getPassword());
                    user.setNickName(s.getNickName());
                    user.setUserTypeId(s.getUserTypeId());
                    return user;
                } else if(users.size() >1){
                    throw new UsernameNotFoundException("用户[" + name + "]找到多个");
                }
                else  {
                    throw new UsernameNotFoundException("用户[" + name + "]不存在");
                }
            }
        };
        return re;
    }





}
